﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Formatters;
using System.Text;
using System.Threading.Tasks;
using Benchmark.Core.Communication.Hub.Impl.Pipe;
using Benchmark.Core.Communication.Hub.Server.Impl.Pipe;
using Benchmark.Core.Communication.Hub.Server.Impl.Pipe.Validation_Set;
using Tcp.Performance.Toolkit.HubServer.Concurrent_Collection;

namespace Tcp.Performance.Toolkit.HubServer
{
    public class HubServer
    {
        private readonly Dictionary<string, AsyncPipeServerEventArgument> _apseaDictionary;
        private readonly HubGuiCollection<HubGuiModel> _hubQueue;
        private readonly ServerValidationSet _validate;

        public HubServer(IEnumerable<string> ipAdrress, HubGuiCollection<HubGuiModel> hubQueue)
        {
            _apseaDictionary = new Dictionary<string, AsyncPipeServerEventArgument>();
            this._hubQueue = hubQueue;
            _validate = new ServerValidationSet();

            foreach (var ip in ipAdrress)
            {
                var apsea = new AsyncPipeServerEventArgument();
                _apseaDictionary.Add(ip, apsea);

            }

        }

        //add to concurrent queue  and switch off any operation button
        private void Lastoperationdone()
        {
        }



        public async void Connect(string ipAdrress, string pipeName)
        {
            var apsea = _apseaDictionary[ipAdrress];
            apsea.OnPostExecutionDelegate = Lastoperationdone;
            bool isCon= true;
            if (apsea.Isconnected != true)
            {
         
             isCon = await apsea.ConnectPipeAsync(pipeName, ipAdrress);
        }

        var model = new HubGuiModel {IpAddress = ipAdrress, IsConnect = isCon};
            _hubQueue.Write(model);
        }






        public async void Initialize<T>(string ip, T initModel)
        {

            AsyncPipeServerEventArgument apsea = _apseaDictionary[ip];
            apsea.OnPostExecutionDelegate = new AsyncPipeServerEventArgument.OnPostExecution(Lastoperationdone);
            var resp = await apsea.InitializeTestAsync<T, string>(initModel);
            bool isInit = _validate.TestOperation<string>(resp,
                Benchmark.Core.Communication.Model.HubModel.OperationType.Initialize);
            var model = new HubGuiModel {IpAddress = ip, IsInit = isInit};
            _hubQueue.Write(model);

        }



        public async void Test(string ip)
        {

            var apsea = _apseaDictionary[ip];
            apsea.OnPostExecutionDelegate = new AsyncPipeServerEventArgument.OnPostExecution(Lastoperationdone);
            string s = Benchmark.Core.Communication.Model.HubModel.OperationType.Test.ToString();
            var resp = await apsea.TestConnectionAsync<string, string>(s);
            bool isTest = _validate.TestOperation<string>(resp,
                Benchmark.Core.Communication.Model.HubModel.OperationType.Test);
            var model = new HubGuiModel {IpAddress = ip, IsTest = isTest};
            _hubQueue.Write(model);

        }



        public async void Execute(string ip)
        {

            var apsea = _apseaDictionary[ip];
            apsea.OnPostExecutionDelegate = new AsyncPipeServerEventArgument.OnPostExecution(Lastoperationdone);

            var resp =
                await
                    apsea.ExecuteTestAync<string, string>(
                        Benchmark.Core.Communication.Model.HubModel.OperationType.Execute.ToString());
            bool isExecute = _validate.TestOperation<string>(resp,
                Benchmark.Core.Communication.Model.HubModel.OperationType.Execute);
            var model = new HubGuiModel {IpAddress = ip, IsExecute = isExecute};
            _hubQueue.Write(model);

        }


        public async void Finish(string ip)
        {


            AsyncPipeServerEventArgument apsea = _apseaDictionary[ip];
            apsea.OnPostExecutionDelegate = new AsyncPipeServerEventArgument.OnPostExecution(Lastoperationdone);
            var resp =
                await
                    apsea.FinishTestAsync<string, string>(
                        Benchmark.Core.Communication.Model.HubModel.OperationType.Finish.ToString());
            bool isFinish = _validate.TestOperation<string>(resp,
                Benchmark.Core.Communication.Model.HubModel.OperationType.Finish);
            var model = new HubGuiModel {IpAddress = ip, IsFinish = isFinish};
            _hubQueue.Write(model);
        }


    }
}
